package com.wang.transfer.util.springBean.resolver;

import com.wang.transfer.util.springBean.annotation.Res;
import com.wang.transfer.util.springBean.beanConfig.BeanFactory;
import com.wang.transfer.util.springBean.util.SpringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.logging.Logger;

/**
 * ResAnnotationResolver: @Res注解解析器
 * @author Mr.wang
 */
public class ResAnnotationResolver {

    private final Logger logger = Logger.getLogger(ResAnnotationResolver.class.getName());

    private final BeanFactory beanFactory;

    private final ArrayList<Class> allClass;

    public ResAnnotationResolver(BeanFactory beanFactory, ArrayList<Class> allClass) {

        this.beanFactory = beanFactory;
        this.allClass = allClass;

        for (Class aClass : allClass) {
            Field[] fields = aClass.getDeclaredFields();
            if (fields.length > 0) {
                for (Field field : fields) {
                    if (field.isAnnotationPresent(Res.class)) {
                        Res res = field.getAnnotation(Res.class);
                        if (!"".equals(res.name())) {
                            // 如果注解上的name不为空，则在beanFactory中查找对应名字的bean
                            Object bean = beanFactory.getBean(res.name());
                            if (bean == null) {
                                // 如果没有找到，则通过类型查找
                                this.iocByType(field, aClass);
                            } else {
                                // 通过名称找到了
                                try {
                                    field.setAccessible(true);
                                    field.set(beanFactory.getBean(SpringUtils.beanNameFormat(aClass)), bean);
                                } catch (IllegalAccessException e) {
                                    e.printStackTrace();
                                }
                            }
                        } else {
                            // 名称为空，则通过类型注入
                            this.iocByType(field, aClass);
                        }
                    }
                }
            }
        }
    }

    /**
     * 通过类型注入方法
     * @param field 字段
     * @param aClass 当前类
     */
    public void iocByType(Field field, Class<?> aClass) {
        Type type = field.getGenericType();
        logger.info("Res type: " + type.getTypeName());
        try {
            Class<?> YClass = Class.forName(type.getTypeName());
            if (YClass.isInterface()) {
                // 如果是接口，则查找实现类
                for (Class a : allClass) {
                    if (YClass.isAssignableFrom(a) && !YClass.equals(a)) {
                        Object beanClass = beanFactory.getBean(SpringUtils.beanNameFormat(a));
                        if (beanClass != null) {
                            // 单例bean存在，拿到类的实例，给字段重新赋值
                            Object bean = beanFactory.getBean(SpringUtils.beanNameFormat(aClass));
                            // 此字段无修饰符，会提示无法访问修饰符为【""】的字段，所以要给他设置访问权限为true
                            field.setAccessible(true);
                            field.set(bean, beanClass);
                        }
                    }
                }
            } else {
                // 不是接口
                Object beanClass = beanFactory.getBean(SpringUtils.beanNameFormat(YClass));
                field.setAccessible(true);
                field.set(beanFactory.getBean(SpringUtils.beanNameFormat(aClass)), beanClass);
            }
        } catch (ClassNotFoundException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
